//
//  BaseVC.m
//  EPTool
//
//  Created by guoshiqing on 2018/4/3.
//  Copyright © 2018年 云数动能. All rights reserved.
//

#import "BaseVC.h"
#import "VCProgressHud.h"
#import "StringUtil.h"
#import "ToastView.h"
#import "BaseViewModel.h"
#import "BaseNavigationController.h"
#import "NotificationHelp.h"
#import "UINavigationBar+FixSpace.h"
#import "Message.h"
#import "ErrorCode.h"
#import "UIView+DDAddition.h"


NS_ASSUME_NONNULL_BEGIN
@interface BaseVC ()

@property (nonatomic, strong) VCProgressHud *hud;
@property (nonatomic, assign) int hudCount;
@property (nonatomic, assign) int hudModalCount;
@property (nonatomic, assign) NSInteger MAXLength;
@end

@implementation BaseVC

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    [self createBackButton];
    self.view.backgroundColor = [EPColor epColor_Bg];
    self.MAXLength = 0;
    
    // BaseVC统一设置状态栏(信号栏)的颜色(背景色白色，文字黑色)，其他界面有不一样的，需要在自己的viewWillAppear里面设置
    self.navigationController.navigationBar.barStyle = UIBarStyleDefault;
    self.navigationController.navigationBar.barTintColor = [UIColor whiteColor];
    [self.navigationController.navigationBar setTitleTextAttributes:@{NSFontAttributeName:[UIFont boldSystemFontOfSize:28.f], NSForegroundColorAttributeName:[UIColor blackColor]}];
    
    [self createViewModel];
    [self createGetBlock];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    
    // 改变导航栏颜色
    [self.navigationController.navigationBar setBarTintColor:[UIColor whiteColor]];
    self.navigationController.navigationBar.barStyle = UIBarStyleDefault;
    self.navigationController.navigationBar.barTintColor = [UIColor whiteColor];
    [self.navigationController.navigationBar setTitleTextAttributes:@{NSFontAttributeName:[UIFont boldSystemFontOfSize:18.f], NSForegroundColorAttributeName:[UIColor blackColor]}];
    
    [self setNavTitleView];
    // 友盟页面统计
    NSString *pageName = NSStringFromClass([self class]);
    [MobClick beginLogPageView:pageName];
}

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
    
    // 改变导航栏颜色
    [self.navigationController.navigationBar setBarTintColor:[UIColor whiteColor]];

    // 友盟页面统计
    NSString *pageName = NSStringFromClass([self class]);
    [MobClick endLogPageView:pageName];
}

#pragma mark - 设置导航栏
- (void)setNavTitleView
{
//    if (@available(iOS 11.0, *)) {
//        self.tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
//    }
    
//    // 设置UIViewController的View和导航栏的显示关系，这三种方式都可以
//    //    self.edgesForExtendedLayout = UIRectEdgeAll;
    self.extendedLayoutIncludesOpaqueBars = NO;
    self.navigationController.navigationBar.translucent = NO;
    [self.navigationController setNavigationBarHidden:NO animated:NO];
}

- (void)createViewModel
{
    if (!self.baseVM) return;
    
    WEAKSELF
    [self.baseVM setBlockWithReturnBlock:^(BaseJSONEntity *returnValue) {
        if ([weakSelf respondsToSelector:@selector(handelRequestData:)]) {
            weakSelf.placeholderView.hidden = YES;
            [weakSelf handelRequestData:returnValue];
        }
    } WithErrorBlock:^(BaseJSONEntity *errorValue) {
        if ([weakSelf respondsToSelector:@selector(handelRequestData:)]) {
            if (C_BeKick == errorValue.ret) {
                // 被踢，跳到登录页面
                [NotificationHelp postNotification:NotificationGo2LoginVC object:errorValue.msg];
                return;
            }
            else if (C_LoseLogin == errorValue.ret  || C_Invalid == errorValue.ret)
            {
                [NotificationHelp postNotification:NotificationGo2LoginVC object:nil];
                return;
            }
            weakSelf.placeholderView.hidden = YES;
            [weakSelf handelRequestData:errorValue];
        }
    } WithFailureBlock:^(BaseJSONEntity *failureValue){
        if ([weakSelf respondsToSelector:@selector(handelRequestData:)]) {
            weakSelf.placeholderView.hidden = YES;
            [weakSelf handelRequestData:failureValue];
        }
    }];
}

#pragma mark - get请求(给天气使用)
- (void)createGetBlock
{
    if (!self.baseVM) return;
    
    WEAKSELF
    [self.baseVM getReturnBlockWithReturnBlock:^(id returnValue, NSString *url) {
        if ([weakSelf respondsToSelector:@selector(getRequestData:andUrl:andError:)]) {
            [weakSelf getRequestData:returnValue andUrl:url andError:nil];
        }
    } WithErrorBlock:^(id errorValue, NSString *url) {
        
        if ([weakSelf respondsToSelector:@selector(getRequestData:andUrl:andError:)]) {
            [weakSelf getRequestData:nil andUrl:url andError:errorValue];
        }
    } WithFailBlock:^(id failValue, NSString *url) {
        if ([weakSelf respondsToSelector:@selector(getRequestData:andUrl:andError:)]) {
            [weakSelf getRequestData:nil andUrl:url andError:failValue];
        }
    }];
}

#pragma mark - 隐藏键盘
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event
{
    [self.view endEditing:YES];
}

#pragma mark - 隐藏导航栏左边返回按钮
- (void)hideBackButton
{
    if (self.leftNavButton) {
        self.leftNavButton.hidden = YES;
    }
}

#pragma mark - 导航栏左边返回按钮
- (void)createBackButton
{
    if (!self.leftNavButton || ![self.leftNavButton isKindOfClass:UIButton.class]) {
        self.leftNavButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 60, 30)];
//        if (IS_IPHONE4 || IS_IPHONE5) {
        if (!IOS11) {
            self.leftNavButton.frame = CGRectMake(0, 0, 30, 30);
            [self.leftNavButton setImageEdgeInsets:UIEdgeInsetsMake(0, 0, 0, 0)];
        } else {
            [self.leftNavButton setImageEdgeInsets:UIEdgeInsetsMake(0, 0, 0, 40)];
        }
        [self createNavLeftBtnWithImageName:@"icon_return"];
    }
}

#pragma mark - 导航栏左边按钮
- (void)createNavLeftBtnWithImageName:(NSString *)imageName
{
    if (!self.leftNavButton || ![self.leftNavButton isKindOfClass:UIButton.class]) {
        self.leftNavButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 60, 30)];
        [self.leftNavButton setImageEdgeInsets:UIEdgeInsetsMake(0, 0, 0, 30)];
    }
    [self.leftNavButton setBackgroundColor:[UIColor clearColor]];
    [self.leftNavButton setContentMode:UIViewContentModeLeft];
    UIBarButtonItem *rightItem = [[UIBarButtonItem alloc] initWithCustomView:self.leftNavButton];
    [self.navigationItem setLeftBarButtonItem:rightItem];
    [self.leftNavButton addTarget:self action:@selector(btnBackClick:) forControlEvents:UIControlEventTouchUpInside];
    
    [self.leftNavButton setImage:[[UIImage imageNamed:imageName] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal] forState:UIControlStateNormal];
}

- (void)btnBackClick:(id)sender
{
    if (self.leftNavButtonBlock) {
        self.leftNavButtonBlock();
    }
    else{
        [self dismissVC];
    }
}

#pragma mark - 导航栏右边按钮
#pragma mark -- 导航栏右边"纯文字"按钮
- (void)createNavBarRightButtonWithName:(NSString *)titleName
{
    [self createNavBarRightButtonWithName:titleName andImageName:@"" andTitleColor:[EPColor epColor_Nav]];
}
- (void)createNavBarRightButtonWithName:(NSString *)titleName withColor:(UIColor *)color
{
    [self createNavBarRightButtonWithName:titleName andImageName:@"" andTitleColor:color];
}
- (void)createNavBarRightButtonWithNameList:(NSArray *)titleNameList
{
    [self createNavBarRightButtonWithNameList:titleNameList andImageNameList:@[] andTitleColor:[EPColor epColor_Blue]];
}

#pragma mark -- 导航栏右边"纯图案"按钮
- (void)createNavBarRightButtonWithImageName:(NSString *)imageName
{
    [self createNavBarRightButtonWithName:@"" andImageName:imageName andTitleColor:[UIColor clearColor]];
}

- (void)createNavBarRightButtonWithImageNameList:(NSArray *)imageNameList
{
    [self createNavBarRightButtonWithNameList:@[] andImageNameList:imageNameList andTitleColor:[UIColor clearColor]];
}

- (void)createNavBarRightButtonWithNameList:(NSArray *)titleNameList andImageNameList:(NSArray *)imageNameList andTitleColor:(UIColor *)color
{
    NSMutableArray *btnArr = [[NSMutableArray alloc] init];
    // 只有文字
    if (0 != titleNameList.count && (nil == imageNameList || 0 == imageNameList.count)) {
        for (int i = 0; i < titleNameList.count; i++) {
            UIButton* btnRightBar = [[UIButton alloc] initWithFrame:CGRectMake(0,0,45,40)];
//            CGFloat right = (90 * i) + 20;
            [btnRightBar setTitleEdgeInsets:UIEdgeInsetsMake(0, 0, 0, -15)];
            [btnRightBar setTitle:titleNameList[i] forState:UIControlStateNormal];
            [btnRightBar setTitleColor:color forState:UIControlStateNormal];
            [btnRightBar.titleLabel setFont:[UIFont systemFontOfSize:16.f]];
            btnRightBar.tag = i;
            [btnRightBar addTarget:self action:@selector(btnNavBarRightBtnListClick:) forControlEvents:UIControlEventTouchUpInside];
            
            UIBarButtonItem *rightItem = [[UIBarButtonItem alloc] initWithCustomView:btnRightBar];
            [btnArr addObject:rightItem];
        }
    }
    // 只有图片
    else if ((nil == titleNameList || 0 == titleNameList.count) && nil != imageNameList) {
        for (int i = 0; i < imageNameList.count; i++) {
            UIButton* btnRightBar = [[UIButton alloc] initWithFrame:CGRectMake(0,0,45,22)];
            [btnRightBar setImageEdgeInsets:UIEdgeInsetsMake(0, 0, 0, -15)];
            [btnRightBar setImage:[UIImage imageNamed:imageNameList[i]] forState:UIControlStateNormal];
            btnRightBar.tag = i;
            [btnRightBar addTarget:self action:@selector(btnNavBarRightBtnListClick:) forControlEvents:UIControlEventTouchUpInside];
            
            UIBarButtonItem *rightItem = [[UIBarButtonItem alloc] initWithCustomView:btnRightBar];
            [btnArr addObject:rightItem];
        }
    }
    self.navigationItem.rightBarButtonItems = btnArr;
}

- (void)createNavBarRightButtonWithName:(NSString *)titleName andImageName:(NSString *)imageName andTitleColor:(UIColor *)color
{
    // 添加导航栏右边按钮
    UIButton* btnRightBar = [[UIButton alloc] initWithFrame:CGRectMake(0,0,64,40)];
    [btnRightBar setImage:[UIImage imageNamed:imageName] forState:UIControlStateNormal];
    [btnRightBar setImage:[UIImage imageNamed:imageName] forState:UIControlStateHighlighted];
    
    // 只有文字
    if (0 != titleName.length && (nil == imageName || 0 == imageName.length)) {
        [btnRightBar setTitleEdgeInsets:UIEdgeInsetsMake(0, 0, 0, -20)];
    }
    // 只有图片
    else if ((nil == titleName || 0 == titleName.length) && nil != imageName) {
        btnRightBar.frame = CGRectMake(0, 0, 22.0, 22.0);
    }
    // 图片和文字都有
    else
    {
        [btnRightBar setTitleEdgeInsets:UIEdgeInsetsMake(0, 0, 0, -20)];
    }
    
    [btnRightBar setTitle:titleName forState:UIControlStateNormal];
    [btnRightBar setTitleColor:color forState:UIControlStateNormal];
    [btnRightBar.titleLabel setFont:[UIFont systemFontOfSize:16.f]];
    [btnRightBar addTarget:self action:@selector(btnNavBarRightBtnClick:) forControlEvents:UIControlEventTouchUpInside];
    
    UIBarButtonItem *rightItem = [[UIBarButtonItem alloc] initWithCustomView:btnRightBar];
    self.navigationItem.rightBarButtonItem = rightItem;
}

- (void)rightBarButtonWithStyle:(BOOL)isEnable
{
    // 没有定义过导航栏右边按钮，就返回
    if (nil == self.navigationItem.rightBarButtonItem || 1 != self.navigationItem.rightBarButtonItems.count) return;
    UIButton *btnRightBar = self.navigationItem.rightBarButtonItem.customView;
    if (![btnRightBar isKindOfClass:[UIButton class]]) return;
    if (isEnable) {
        btnRightBar.enabled = YES;
        [btnRightBar setTitleColor:[EPColor epColor_Nav] forState:UIControlStateNormal];
    }
    else
    {
        btnRightBar.enabled = NO;
        [btnRightBar setTitleColor:[EPColor epColor_descMessageGray] forState:UIControlStateNormal];
    }
}

- (void)btnNavBarRightBtnClick:(id)sender
{
    if (self.rightNavButtonBlock) {
        self.rightNavButtonBlock();
    }
}

- (void)btnNavBarRightBtnListClick:(UIButton *)btn
{
    if (self.rightNavButtonListBlock) {
        self.rightNavButtonListBlock(btn.tag);
    }
}

#pragma mark - 懒加载
- (NSMutableArray *)observerList
{
    if (!_observerList){
        _observerList = [NSMutableArray new];
    }
    return _observerList;
}

- (VCProgressHud *)hud
{
    if (!_hud) {
        _hud = [[VCProgressHud alloc] initWithSuperView:self.view];
        _hud.layer.zPosition = 9999;
    }
    return _hud;
}


#pragma mark - 弹出对话框
- (void)showAlertWithMessage:(NSString *)message
{
    [self showAlertWithMessage:message handler:nil];
}
- (void)showAlertWithTitle:(NSString *)title
{
    [self showAlertWithTitle:title handler:nil];
}

- (void)showAlertWithMessage:(NSString *)message handler:(void (^ __nullable)(UIAlertAction *action))handler
{
    UIAlertController * alert = [UIAlertController alertControllerWithTitle:@"提示" message:message preferredStyle:UIAlertControllerStyleAlert];
    UIAlertAction * cancelAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleCancel handler:handler];
    [cancelAction setValue:[EPColor epColor_Blue] forKey:@"titleTextColor"];
    [alert addAction:cancelAction];
    
    // 解决ipad闪退问题
    if ([alert respondsToSelector:@selector(popoverPresentationController)]) {
        alert.popoverPresentationController.sourceView = self.view;
    }
    [self presentViewController:alert animated:YES completion:nil];
}

- (void)showAlertWithTitle:(NSString *)title handler:(void (^ __nullable)(UIAlertAction *action))handler
{
    UIAlertController * alert = [UIAlertController alertControllerWithTitle:title message:@"" preferredStyle:UIAlertControllerStyleAlert];
    UIAlertAction * cancelAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleCancel handler:handler];
    [cancelAction setValue:[EPColor epColor_Blue] forKey:@"titleTextColor"];
    [alert addAction:cancelAction];
    
    // 解决ipad闪退问题
    if ([alert respondsToSelector:@selector(popoverPresentationController)]) {
        alert.popoverPresentationController.sourceView = self.view;
    }
    [self presentViewController:alert animated:YES completion:nil];
}

- (void)showAlertWithMessage:(NSString *)message cancel:(void (^ __nullable)(UIAlertAction *action))cancelHandler sure:(void (^ __nullable)(UIAlertAction *action))sureHandler
{
    [self showAlertWithMessage:message title:@"提示" cancel:cancelHandler sure:sureHandler];
}

- (void)showAlertWithTitle:(NSString *)title cancel:(void (^ __nullable)(UIAlertAction *action))cancelHandler sure:(void (^ __nullable)(UIAlertAction *action))sureHandler
{
    [self showAlertWithMessage:@"" title:title cancel:cancelHandler sure:sureHandler];
}

- (void)showAlertWithMessage:(NSString *)message title:(NSString *)title cancel:(void (^ __nullable)(UIAlertAction *action))cancelHandler sure:(void (^ __nullable)(UIAlertAction *action))sureHandler
{
    [self showAlertWithMessage:message title:title cancelStr:@"取消" sureStr:@"确定" cancel:cancelHandler sure:sureHandler];
}

- (void)showAlertWithMessage:(NSString *)message title:(NSString *)title cancelStr:(NSString *)cancelStr sureStr:(NSString *)sureStr cancel:(void (^ __nullable)(UIAlertAction *action))cancelHandler sure:(void (^ __nullable)(UIAlertAction *action))sureHandler
{
    UIAlertController * alert = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
     
    UIAlertAction * cancelAction = [UIAlertAction actionWithTitle:cancelStr style:UIAlertActionStyleCancel handler:cancelHandler];
    [cancelAction setValue:[EPColor epColor_Blue] forKey:@"titleTextColor"];
    [alert addAction:cancelAction];
    
    UIAlertAction * surelAction = [UIAlertAction actionWithTitle:sureStr style:UIAlertActionStyleDefault handler:sureHandler];
    [surelAction setValue:[EPColor epColor_Blue] forKey:@"titleTextColor"];
    [alert addAction:surelAction];
    
    // 解决ipad闪退问题
    if ([alert respondsToSelector:@selector(popoverPresentationController)]) {
        alert.popoverPresentationController.sourceView = self.view;
    }
    [self presentViewController:alert animated:YES completion:nil];
}

- (void)showAlertForInputPwdSuccess:(void (^)(NSString *password))success failure:(void (^)(void))failure
{
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"验证密码" message:@"如果忘记密码，请登出并通过忘记密码找回" preferredStyle:UIAlertControllerStyleAlert];
    
    [alertController addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
        failure();
    }]];
    
    __block UITextField *txfPwd;
    [alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
        txfPwd = textField;
    }];
    
    [alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"Confirm", @"确定") style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        
        NSString *pwd = [StringUtil trimHeadTail:[NSCharacterSet whitespaceAndNewlineCharacterSet] forString:txfPwd.text];
        if (0 != pwd.length) {
            success(pwd);
        }
        else
        {
            [ToastView showMsg:NSLocalizedString(@"PasswordCanNotBeEmpty", @"密码不能为空！")];
//            [weakSelf presentViewController:alertController animated:YES completion:nil];
            return ;
        }
    }]];
    
    // 解决ipad闪退问题
    if ([alertController respondsToSelector:@selector(popoverPresentationController)]) {
        alertController.popoverPresentationController.sourceView = self.view;
    }
    [self presentViewController:alertController animated:YES completion:nil];
}

- (void)showAlertForInputWithTitle:(NSString *)title Message:(NSString *)message andMaxNum:(NSInteger)maxNum Success:(void (^)(NSString *txfText))success failure:(void (^)(void))failure
{
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
    
    [alertController addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
        failure();
    }]];
    
    __block UITextField *txfText;
    WEAKSELF
    [alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
        txfText = textField;
        if (maxNum && maxNum > 0) {
            weakSelf.MAXLength = maxNum;
            [txfText addTarget:weakSelf action:@selector(numberAgaintextFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
        }
    }];
    
    [alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"Confirm", @"确定") style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        
        if (0 != txfText.text.length) {
            success(txfText.text);
        }
        else
        {
            [ToastView showMsg:NSLocalizedString(@"ContentCanNotBeEmpty", @"内容不能为空！")];
        }
    }]];
    
    // 解决ipad闪退问题
    if ([alertController respondsToSelector:@selector(popoverPresentationController)]) {
        alertController.popoverPresentationController.sourceView = self.view;
    }
    [self presentViewController:alertController animated:YES completion:nil];
}

- (void)showAlertWithItemNameList:(NSArray <NSString *> *)nameList withBlock:(void (^ __nullable)(NSUInteger index, NSString *itemName))block
{
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
    
    for (int i = 0; i < nameList.count; ++i) {
        NSString *itemName = [nameList objectAtIndex:i];
        UIAlertAction *action = [UIAlertAction actionWithTitle:itemName style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
            NSUInteger index = [nameList indexOfObject:action.title];
            block(index, action.title);
        }];
        [action setValue:[EPColor epColor_Blue] forKey:@"titleTextColor"];
        [alertController addAction:action];
    }
    UIAlertAction *cancleAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil];
    [cancleAction setValue:[EPColor epColor_Blue] forKey:@"titleTextColor"];
    [alertController addAction:cancleAction];
    
    // 解决ipad闪退问题
    if ([alertController respondsToSelector:@selector(popoverPresentationController)]) {
        alertController.popoverPresentationController.sourceView = self.view;
    }
    [self presentViewController:alertController animated:YES completion:nil];
}

- (void)showAlertWithItemNameList:(NSArray <NSString *> *)nameList withColor:(NSArray <UIColor *> *)colorList withBlock:(void (^ __nullable)(NSUInteger index, NSString *itemName))block
{
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
    
    for (int i = 0; i < nameList.count; ++i) {
        NSString *itemName = [nameList objectAtIndex:i];
        UIAlertAction *action = [UIAlertAction actionWithTitle:itemName style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
            NSUInteger index = [nameList indexOfObject:action.title];
            block(index, action.title);
        }];
        [action setValue:colorList[i] forKey:@"titleTextColor"];
        [alertController addAction:action];
    }
    UIAlertAction *cancleAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil];
    [cancleAction setValue:[EPColor epColor_Blue] forKey:@"titleTextColor"];
    [alertController addAction:cancleAction];
    
    // 解决ipad闪退问题
    if ([alertController respondsToSelector:@selector(popoverPresentationController)]) {
        alertController.popoverPresentationController.sourceView = self.view;
    }
    [self presentViewController:alertController animated:YES completion:nil];
}

- (void)numberAgaintextFieldDidChange:(UITextField *)textField
{
    if (self.MAXLength == 0) return;
    NSInteger number = textField.text.length;
    if (number > self.MAXLength) {
        textField.text = [textField.text substringToIndex:self.MAXLength];
    }
}

#pragma mark - hud控制函数
/**
 * 模态Hud
 */
- (void)showProcessingHud_Modal:(NSString *)msg
{
    MainQueue(^{
        ++self.hudModalCount;
        if ([UIApplication sharedApplication].isIgnoringInteractionEvents == NO) {
            [[UIApplication sharedApplication] beginIgnoringInteractionEvents];
        }
        [self.hud showWithStatus:msg];
    });
}

- (void)hideProcessingHud_Modal
{
    --self.hudModalCount;
    if (self.hudModalCount <= 0) {
        if ([UIApplication sharedApplication].isIgnoringInteractionEvents == YES) {
            [[UIApplication sharedApplication] endIgnoringInteractionEvents];
        }
        [self.hud dismiss];
    }
}


/**
 * 基本Hud
 */
- (void)showProcessingHud_Free:(NSString *)msg
{
    ++self.hudCount;
    [self.hud showWithStatus:msg];
}
- (void)showProcessingHud:(NSString *)msg
{
    ++self.hudCount;
    [self.view setUserInteractionEnabled:NO];
    [self.hud showWithStatus:msg];
}
- (void)hideProcessingHud
{
    --self.hudCount;
    if (self.hudCount <= 0) {
        [self dismissProcessingHud];
    }
}

/*
 * 强制取消Hud
 */
- (void)dismissProcessingHud_Modal
{
    self.hudModalCount = 0;
    if ([UIApplication sharedApplication].isIgnoringInteractionEvents == YES) {
        [[UIApplication sharedApplication] endIgnoringInteractionEvents];
    }
    [self.hud dismiss];
}
- (void)dismissProcessingHud
{
    self.hudCount = 0;
    __weak typeof(self) weakSelf = self;
    dispatch_async(dispatch_get_main_queue(), ^{
        [weakSelf.view setUserInteractionEnabled:YES];
    });
    [self.hud dismiss];
}


#pragma mark - 页面生命周期控制函数
- (void)dealloc
{
    for (id observer in self.observerList){
        [[NSNotificationCenter defaultCenter] removeObserver:observer];
    }
    [self.observerList removeAllObjects];
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    
    NSLog(@"dealloc VC = %@", NSStringFromClass([self class]));
}

- (void)destroy
{
    for (id observer in self.observerList){
        [[NSNotificationCenter defaultCenter] removeObserver:observer];
    }
    
    [self.observerList removeAllObjects];
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

- (void)dismissVC
{
    if (self.navigationController) {
        if (self.navigationController.viewControllers && self.navigationController.viewControllers.count <= 1) {
            [self.navigationController dismissViewControllerAnimated:YES completion:^{}];
        } else {
            [self.navigationController popViewControllerAnimated:YES];
        }
    } else {
        [self dismissViewControllerAnimated:YES completion:^{}];
    }
}

#pragma mark - 跳转到某个控制器，参数为控制器名字
- (void)popToVCWithVCName:(NSString *)vcName
{
    for (UIViewController *controller in self.navigationController.viewControllers) {
        
        if ([controller isKindOfClass:NSClassFromString(vcName)]) {
            
            [self.navigationController popToViewController:controller animated:YES];
            return;
        }
    }
    [self.navigationController popViewControllerAnimated:YES];
}


#pragma mark - 获取最顶层的控制器
- (UIViewController *)topViewController
{
    return [self topViewControllerWithRootViewController:[[[UIApplication sharedApplication] delegate] window].rootViewController];
}

- (UIViewController *)topViewControllerWithRootViewController:(UIViewController*)rootViewController
{
    if ([rootViewController isKindOfClass:[UITabBarController class]]) {
        
        UITabBarController *tabBarController = (UITabBarController *)rootViewController;
        return [self topViewControllerWithRootViewController:tabBarController.selectedViewController];
        
    }else if ([rootViewController isKindOfClass:[UINavigationController class]]) {
        
        UINavigationController* navigationController = (UINavigationController*)rootViewController;
        return [self topViewControllerWithRootViewController:navigationController.visibleViewController];
        
    }else if (rootViewController.presentedViewController) {
        
        UIViewController* presentedViewController = rootViewController.presentedViewController;
        return [self topViewControllerWithRootViewController:presentedViewController];
        
    }else {
        
        return rootViewController;
    }
}

// 根据名字找返回这个控制器
- (UIViewController *)returnVCWithVCName:(NSString *)vcName
{
    for (UIViewController *controller in self.navigationController.viewControllers) {
        
        if ([controller isKindOfClass:NSClassFromString(vcName)]) {
            
            return controller;
        }
    }
    return nil;
}


#pragma mark - 占位图
- (PlaceholderView *)placeholderView
{
    if (!_placeholderView) {
        _placeholderView = [[PlaceholderView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
        _placeholderView.hintOperateBtnName = nil;
        _placeholderView.userInteractionEnabled = YES;
        _placeholderView.hidden = NO;
        [self.view addSubview:_placeholderView];
    }
    return _placeholderView;
}

// 网络不可达占位图
- (void)showNetUnreachableImageName:(NSString *)name andBlock:(OperateBtnBlock)block
{
    self.placeholderView.hintImageName = (nil != name && 0 != name.length)?name:@"placeholder_unreachable";
    self.placeholderView.hintText = NSLocalizedString(@"G_PH_NetUnreachable", @"网络异常，请刷新尝试");
    self.placeholderView.hintOperateBtnName = NSLocalizedString(@"G_PH_Refresh", @"刷新");
    self.placeholderView.height = UI_CONTENT_HEIGHT;
    self.placeholderView.hidden = NO;
    self.placeholderView.block = block;
}

// 网络请求失败占位图
- (void)showNetFailureImageName:(NSString *)name andBlock:(OperateBtnBlock)block
{
    self.placeholderView.hintImageName = (nil != name && 0 != name.length)?name:@"placeholder_failure";
    self.placeholderView.hintText = NSLocalizedString(@"G_PH_NetFailure", @"数据加载失败");
    self.placeholderView.hintOperateBtnName = NSLocalizedString(@"G_PH_Retry", @"重试");
    self.placeholderView.height = UI_CONTENT_HEIGHT;
    self.placeholderView.hidden = NO;
    self.placeholderView.block = block;
}

// 暂无数据占位图
- (void)showNoDataImageName:(NSString *)name andMessage:(nullable NSString *)message
{
    self.placeholderView.hintText = (!message || 0 == message.length)?NSLocalizedString(@"G_PH_NoData", @"暂无数据"):message;
    self.placeholderView.hintImageName = (nil != name && 0 != name.length)?name:@"placeholder_nodata";
    self.placeholderView.hintOperateBtnName = nil;
    self.placeholderView.height = UI_CONTENT_HEIGHT;
    self.placeholderView.hidden = NO;
}

// 暂无数据占位图但，但是有发布按钮
- (void)showNoDataImageName:(NSString *)name andMessage:(nullable NSString *)message withSignBtn:(nullable NSString *)btn andBlock:(OperateBtnBlock)block
{
    self.placeholderView.hintText = (!message || 0 == message.length)?NSLocalizedString(@"G_PH_NoData", @"暂无数据"):message;
    self.placeholderView.hintImageName = (nil != name && 0 != name.length)?name:@"placeholder_nodata";
    self.placeholderView.hintOperateBtnName = btn;
    self.placeholderView.height = UI_CONTENT_HEIGHT;
    self.placeholderView.hidden = NO;
    self.placeholderView.block = block;
}


#pragma mark - 设置动画转场
- (HorizontalSwipeInteractionController *)percentDrivenInteractiveTransition{
    if (nil == _percentDrivenInteractiveTransition) {
        _percentDrivenInteractiveTransition = [[HorizontalSwipeInteractionController alloc]init];
    }
    return _percentDrivenInteractiveTransition;
}

- (PanAnimationController *)viewControllerAnimatedTransitioning{
    if (nil == _viewControllerAnimatedTransitioning) {
        _viewControllerAnimatedTransitioning = [[PanAnimationController alloc]init];
    }
    return _viewControllerAnimatedTransitioning;
}

- (id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source {
    
    [self.percentDrivenInteractiveTransition wireToViewController:presented forOperation:InteractionOperationDismiss];
    self.viewControllerAnimatedTransitioning.reverse = NO;
    return self.viewControllerAnimatedTransitioning;
    
}

- (id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed {
    self.viewControllerAnimatedTransitioning.reverse = YES;
    return self.viewControllerAnimatedTransitioning;
}

- (id<UIViewControllerInteractiveTransitioning>)interactionControllerForDismissal:(id<UIViewControllerAnimatedTransitioning>)animator {
    return self.percentDrivenInteractiveTransition.interactionInProgress ? self.percentDrivenInteractiveTransition : nil;
}

- (void)enablePanInteraction{
    UIViewController* vc = self;
    id transitioningDelegate = vc.transitioningDelegate;
    
    while (vc && !transitioningDelegate) {
        vc = vc.parentViewController;
        transitioningDelegate = vc.transitioningDelegate;
    }
    
    if (transitioningDelegate && [transitioningDelegate isKindOfClass:[BaseVC class]]) {
        [((BaseVC *)transitioningDelegate).percentDrivenInteractiveTransition enablePanInteraction];
    }
}

- (void)disablePanInteraction{
    UIViewController* vc = self;
    id transitioningDelegate = vc.transitioningDelegate;
    
    while (vc && !transitioningDelegate) {
        vc = vc.parentViewController;
        transitioningDelegate = vc.transitioningDelegate;
    }
    
    if (transitioningDelegate && [transitioningDelegate isKindOfClass:[BaseVC class]]) {
        [((BaseVC *)transitioningDelegate).percentDrivenInteractiveTransition disablePanInteraction];
    }
}

- (void)presentViewController:(BaseVC *)controller{
    
    controller.controllerShowMode   = NVControllerShowModePresent;
    
    UINavigationController* nvc     = [[UINavigationController alloc]initWithRootViewController:controller];
    nvc.transitioningDelegate       = self;
    
    [self presentViewController:nvc animated:YES completion:nil];
}

@end
NS_ASSUME_NONNULL_END
